﻿// --------------------------------
// <copyright file="ADisplayable.cs" company="Faculty of Information Technology, Czech Technical University in Prague">
//     This document is shared by Microsoft Public License (MS-PL)
//     For further details please see http://msdn.microsoft.com/en-us/library/ff648068.aspx or license.txt.
// </copyright>
// <author>Lukáš Molnár</author>

// <email>molnaluk@fit.cvut.cz</email>

// <date>9. 11. 2011 22:22:37</date>

// <summary>
//
// </summary>
// --------------------------------

#if WINDOWS

using System.ComponentModel;

#endif

using System.Xml.Serialization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using FITClub.Util;

namespace FITClub.TextureMenu
{
#if WINDOWS

    [System.Serializable]
#endif
    /// <summary>
    /// Base class for all active/inactive menu items.
    /// </summary>
    public abstract class ADisplayable : IDisplayable
    {
        /// <summary>
        /// True if should be this item displayed.
        /// Default: true
        /// </summary>
        [XmlAttribute]
#if WINDOWS
        [Category("Design")]
#endif
        public bool Visible { get; set; }

        /// <summary>
        /// Determinates draw order among all active or among all inactive items.
        /// </summary>
        [XmlAttribute]
#if WINDOWS
        [Category("Design")]
#endif
        public int Order { get; set; }

        /// <summary>
        /// Unique identifier.
        /// </summary>
        [XmlAttribute]
#if WINDOWS
        [Category("Design")]
#endif
        public string Name { get; set; }

        /// <summary>
        /// Should be item resized
        /// </summary>
#if WINDOWS

        [Category("Behaviour")]
#endif
        [XmlAttribute]
        public bool Resizable { get; set; }

        /// <summary>
        /// Position and size of element.
        /// </summary>
#if WINDOWS

        [Category("Design")]
#endif
        [XmlElement]
        public Rectangle Bounds { get; set; }

        /// <summary>
        /// False if content should be loaded.
        /// </summary>
#if WINDOWS

        [Browsable(false)]
#endif
        [XmlIgnore]
        public bool ContentLoaded { get; set; }

        /// <summary>
        /// Menu, where is item displayed.
        /// </summary>
        [XmlIgnore]
#if WINDOWS
        [System.NonSerialized]
#endif
        public Menu Owner;

        public ADisplayable()
        {
            this.Visible = true;
            this.Resizable = true;
        }

#if WINDOWS_PHONE == false

        /// <summary>
        /// Computes new position and size on screen resize.
        /// </summary>
        /// <param name="ratioX">Delta ratio of width/X.</param>
        /// <param name="ratioY">Delta ratio of height/Y.</param>
        public virtual void Resized(double ratioX, double ratioY)
        {
            if (Resizable)
            {
                Bounds = new Rectangle((int)(Bounds.X * ratioX), (int)(Bounds.Y * ratioY), (int)(Bounds.Width * ratioX), (int)(Bounds.Height * ratioY));
            }
        }

#endif

        /// <summary>
        /// Loads element's content such as textures, fonts etc.
        /// </summary>
        /// <param name="loader"></param>
        public abstract void LoadContent(Microsoft.Xna.Framework.Content.ContentManager loader);

        public abstract void Dispose();

        /// <summary>
        /// Change item's position using step.
        /// </summary>
        /// <param name="delta"></param>
        public virtual void Move(Point delta)
        {
            this.Bounds = Bounds.OffsetXY(delta.X, delta.Y);
        }

        /// <summary>
        /// Draw item only if is visible.
        /// Invoked from owner's Draw method.
        /// </summary>
        /// <param name="spriteBatch"></param>
        /// <param name="tint"></param>
        public void DrawVisible(SpriteBatch spriteBatch, Color tint)
        {
            if (this.Visible)
            {
                this.Draw(spriteBatch, tint);
            }
        }

        /// <summary>
        /// Draw item carelessly the visibility.
        /// </summary>
        /// <param name="spriteBatch"></param>
        /// <param name="tint">Tint color.</param>
        public abstract void Draw(SpriteBatch spriteBatch, Color tint);

        public override string ToString()
        {
            return string.Format("{0} [{1},{2}] {3}", this.GetType().Name, this.Bounds.X, this.Bounds.Y, this.Name);
        }

#if WINDOWS

        /// <summary>
        ///
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public virtual ADisplayable Clone(Microsoft.Xna.Framework.Content.ContentManager content)
        {
            ADisplayable ad = FITClub.Util.ObjectCopier.Clone<ADisplayable>(this);
            ad.ContentLoaded = false;
            ad.Owner = this.Owner;
            ad.LoadContent(content);
            return ad;
        }

#endif
    }
}